//
//  CrossScript.h
//

#ifndef CrossScript_h
#define CrossScript_h

typedef char* (*ScriptHost) (int aid, const char* param1, const char* param2, const char* param3);
typedef void (*ScriptWriteLn) (int aid, const char* str);
typedef char* (*ScriptRunLine) (int aid, const char* unitName, const char* srcPos);

/**
 * 注册脚本内 HOST 指令的回调
 */
extern void registerScriptHost(ScriptHost m);
/**
 * 注册脚本内 WriteLn 指令的回调
 */
extern void registerScriptWriteLn(ScriptWriteLn m);
/**
 * 注册脚本调试器回调
 */
extern void registerScriptRunLine(ScriptRunLine m);

/**
 * 加载原生插件
 * @param basePath 插件所在的路径
 */
extern void loadNativePlugin(const char* basePath);
/**
 * 加载一个未经编译的脚本源码文件
 * @param filePath 文件路径
 * @return 脚本ID，加载失败返回-1
 */
extern int addScriptFile(const char* filePath);
/**
 * 加载一个脚本源码字符串
 * @param text 源码字符串
 * @return 脚本ID，加载失败返回-1
 */
extern int addScriptText(const char* text);
/**
 * 加载一个经过编译的脚本文件
 * @param filePath 文件路径
 * @return 脚本ID，加载失败返回-1
 */
extern int addScriptBinary(const char* filePath);
/**
 * 添加一个引用路径，该路径指出了脚本代码中的 include/import/uses 相关标记所能够查找的代码目录
 * @param id 脚本ID
 * @param path 引用路径（纯路径，不包含文件名）
 */
extern void addIncludePath(int aid, const char* path);
/**
 * 设置是否允许按行中断，允许的情况下，即是调试开启的状态
 * @param id 脚本ID
 * @param canInterrupt 是否允许
 */
extern void setRunLineInterrupt(int aid, BOOL canInterrupt);
/**
 * 移除脚本
 * @param id 脚本ID
 * @return 是否移除成功
 */
extern BOOL removeScript(int id);
/**
 * 执行脚本
 * @param id 脚本ID
 * @return 是否执行成功
 */
extern BOOL runScript(int id);
/**
 * 执行脚本中的特定函数
 * @param id 脚本ID
 * @param AMethodName 函数名
 * @param AParamTypes 参数类型表，参数类型表支持以下类型（i:int, s:string, b:boolean, d:double, l:long, 若是数组则在类型前加a），类型之间用逗号分隔，最后以逗号结尾，如 "s,i,ai,"，该字符串表明了三个参数分别为字符串，整型与整型数组
 * @param AParams 参数值表，全部参数均需要先转换成字符串，如 new String[] { "a", "1", "[1,2,3]"}
 * @return 函数的返回值，若是void函数返回空字符串
 */
extern char* callMethod(int id, const char* AMethodName, const char* AParamTypes, char* AParams[]);
/**
 * 执行脚本中的特定函数
 * @param id 脚本ID
 * @param AMethodName 函数名
 * @param AParamTypes 参数类型表，参数类型表支持以下类型（i:int, s:string, b:boolean, d:double, l:long, 若是数组则在类型前加a），类型之间用逗号分隔，最后以逗号结尾，如 "s,i,ai,"，该字符串表明了三个参数分别为字符串，整型与整型数组
 * @param AParams 参数值表，以json形式组织，如 ["a", 1, [1,2,3]]
 * @return 函数的返回值，若是void函数返回空字符串
 */
extern char* callMetho2(int id, const char* AMethodName, const char* AParamTypes, const char* AParams);
/**
 * 强制停止一个脚本，通常用于在脚本未执行完时强行停止，如在产生死循环的状态下中断
 * @param id 脚本ID
 * @return 是否停止成功
 */
extern BOOL stopScript(int id);
/**
 * 计算一个表达式的值（可以在运行时调用，以实现断点调试时的表达式获取）
 * @param id 脚本ID
 * @param avar 表达式，可以是变量名，函数调用
 * @return 值
 */
extern char* evoluateScriptVariable(int id, const char* avar);
/**
 * 获取运行时错误，仅当 runScript 方法返回 false 时可以调用
 * @param id 脚本ID
 * @return 错误信息
 */
extern char* getErrorMessage(int id);
/**
 * 对脚本进行分析，解析其中的变量与方法成员
 * @param id 脚本ID
 * @return 分析结果json字符串
 */
extern char* analysisScript(int id);
/**
 * 编译一个脚本源码文件
 * @param codePath 源码文件路径
 * @param destPath 目标文件路径
 * @param includePath 编译时引用路径，该路径指出了脚本代码中的 include/import/uses 相关标记所能够查找的代码目录
 * @return 是否编译成功
*/
extern BOOL compile(const char* codePath, const char* destPath; const char* includePath);
/**
 * 获取编译时错误，仅当 compile 方法返回 false 时可以调用
 * @return 错误信息
 */
extern char* getCompileError();
/**
 * 设置是否允许 AOP
 * @param AEnabled 是否允许
 */
extern void setAOPEnabled(BOOL aenabled);
/**
 * 获取 AOP 是否允许
 * @return 是否允许
 */
extern BOOL getAOPEnabled();

#endif /* CrossScript_h */
